#ifndef OBJECTMANAGEMENT_H_INCLUDED
#define OBJECTMANAGEMENT_H_INCLUDED

#include "common.h"
#include "matrixManagement.h"
#include "pixel.h"
#include <vector>

#define NO_OBJECT 65535            //!< No object ID
#define MIN_PX_PER_OBJECT 400      //!< Minimum number of pixel to be considered as an object
#define MAX_IMG_SIZE 65535         //!< Maximum tolerable image border size

#define OBJ_INDEX Uint16           //!< Object ID type

//! \brief Object handling class
//!
//! This class handles the creation and construction of objects. It also stores the object after finalizing it.
//! It then calls the Skeleton and Isobarycenter processing functions
class Object
{
    public:
        Object(OBJ_INDEX** mainMat, OBJ_INDEX index);
        void processSkeleton();
        void processMask();
        void addPoint(Uint16 li, Uint16 col, PixelLab** src);
        void finalize();

        ~Object();


        inline int getCount() const {return m_count;}
        inline bool** getMask() const {return m_mask;}
        inline Taille getSize() const {Taille t = {m_area.h, m_area.w}; return t;}
        inline Pos getOffset() const {Pos p = {m_area.y, m_area.x}; return p;}
        inline Area getArea() const {return m_area;}
        inline Pos getIsobar() const {Pos t = {(Uint16)m_isobar.lign, (Uint16)m_isobar.column}; return t;}
        inline Skeleton* getSkeleton() const {return m_skel;}
        inline PixelLab getMainColor() const {return m_mainColor;}
        inline Pixel getMainRGB() const {return m_mainRGB;}

    private:
        OBJ_INDEX m_index;
        OBJ_INDEX** m_mainMat;
        bool** m_mask;
        Area m_area;
        Skeleton* m_skel;
        LongPos m_isobar;
        int m_count;
        PixelLab m_mainColor;
        Pixel m_mainRGB;
};

//! \brief Main image object decomposition handling class
//!
//! This class handles the creation of a scene (ie: all the object that are created by the object detection).
//! It stores every object in the scene.
class ObjectManager
{
    public:
        ObjectManager(Taille imgSize);
        void processLeftover(PixelLab** src);
        void iterate(void (Object::*ptr)(void));
        bool** getSkeletonMasks();
        void clearObjects();

        ~ObjectManager();


        inline int getCount() const {return m_objs.size();} // Nombre d'objet
        inline OBJ_INDEX** getMat() const {return m_mat;} // Matrice des objets
        inline Taille getSize() const {return m_size;} // Taille

        //! \brief Current object ID accessor
        //!
        //! \return The current object ID
        inline OBJ_INDEX current() const {return getCount();}//objet actuel

        inline std::vector<Object*>& getObjs() {return m_objs;}
        inline Object* getObj(OBJ_INDEX index) const {return m_objs[index];}
        inline Object* getCurrentObj() const {return m_objs[m_current];}

        //! \brief Adds a new object to the object list
        inline void addObject() {m_current++; m_objs.push_back(new Object(m_mat, m_current));} // Ajoute un objet

    private:
        OBJ_INDEX** m_mat;
        std::vector<Object*> m_objs;
        OBJ_INDEX m_current;
        Taille m_size;
};

#endif // OBJECTMANAGEMENT_H_INCLUDED

